package org.springblade.app.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import org.bouncycastle.cert.ocsp.Req;
import org.springblade.app.constant.AppCategoryConstant;
import org.springblade.app.constant.ShySystemConstant;
import org.springblade.app.entity.AppInfoEntity;
import org.springblade.app.entity.AppUserEntity;
import org.springblade.app.feign.IIotAppClient;
import org.springblade.app.feign.ISubAppClient;
import org.springblade.app.service.IAppInfoService;
import org.springblade.app.service.IAppUserService;
import org.springblade.app.utils.UinoUtil;
import org.springblade.app.vo.AppUserVO;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.entity.Dept;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.feign.IUserSearchClient;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhangyr
 * @version 1.0
 * @date 2022-08-23 9:13
 * @description 应用成员表
 */
@RestController
@AllArgsConstructor
@RequestMapping("/shy/app/user")
@Api(value = "应用成员表", tags = "应用成员表")
public class ShyAppUserController {

	private final IAppUserService app_userService;

	private final ISubAppClient subAppClient;

	private final IUserSearchClient userSearchClient;

	private final ISysClient sysClient;

	private final IAppInfoService app_infoService;

	private final IIotAppClient iotAppClient;

	private final UinoUtil uinoUtil;
	/**
	 * 成员列表
	 */
	@GetMapping("/listUser")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "成员列表", notes = "传入app_info")
	public R<IPage<AppUserVO>> listUser(@ApiParam(value = "应用id") @RequestParam String subAppId,
										@RequestParam Integer current,
										@RequestParam Integer size) {
		//查询当前应用所有成员
		Query query = new Query();
		query.setSize(size);
		query.setCurrent(current);
		IPage<AppUserVO> appUserVO = app_userService.page(Condition.getPage(query), subAppId, 1);
		return R.data(appUserVO);
	}


	/**
	 * 部门列表
	 */
	@GetMapping("/listDept")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "部门列表", notes = "传入app_info")
	public R<IPage<AppUserVO>> listDept(@ApiParam(value = "应用id") @RequestParam String subAppId,
									   @RequestParam Integer current,
									   @RequestParam Integer size) {
		//查询当前应用所有部门
		Query query = new Query();
		query.setSize(size);
		query.setCurrent(current);
		IPage<AppUserVO> appDeptVO = app_userService.page(Condition.getPage(query), subAppId, 2);
		return R.data(appDeptVO);
	}

	/**
	 * 成员新增
	 */
	@PostMapping("/add")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "成员新增", notes = "传入app_info")
	@Transactional
	public R<AppInfoEntity> add(@RequestBody Map<String, Object> map) {
		String subAppId = (String) map.get("subAppId");
		Integer linkType = (Integer) map.get("linkType");
		String linkIds = (String) map.get("linkIds");
		Integer isManager = (Integer) map.get("type");
		ArrayList<AppUserEntity> appUsers = new ArrayList<>();
		for (String linkId : linkIds.split(",")) {
			AppUserEntity appUserEntity = app_userService.findBySubAppIdAndLinkId(subAppId, Long.valueOf(linkId));
			if (appUserEntity == null){
				AppUserEntity appUser = new AppUserEntity();
				appUser.setAppId(subAppId);
				appUser.setType(isManager);
				appUser.setLinkType(linkType);
				appUser.setLinkId(Long.valueOf(linkId));
				appUser.setCreateTime(new Date());
				appUsers.add(appUser);
			}
		}
		app_userService.saveBatch(appUsers);
		final AppInfoEntity one = app_infoService.getOne(Wrappers.<AppInfoEntity>query().lambda().eq(AppInfoEntity::getSubAppId, subAppId));

		for (AppUserEntity appUser : appUsers) {
			//同步到子应用中
			if (AppCategoryConstant.SELF_BUILT_APP.equals(one.getCategory())) {
				final R r = subAppClient.addUser(subAppId, linkType, String.valueOf(appUser.getLinkId()));
				subAppClient.setAppManager(subAppId, appUser.getLinkId(), appUser.getType());
				boolean result = false;
				if (r.getCode() == 200) {
					result = true;
				}
				//判断子应用是否执行成功，未成功则手动回滚事务
				if (!result) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return R.fail("同步子应用失败！");
				}
			}
			//同步到物联网子应用中
			if (AppCategoryConstant.IOT_APP.equals(one.getCategory())) {
				final R r = iotAppClient.addUser(subAppId, linkType, String.valueOf(appUser.getLinkId()));
				iotAppClient.setAppManager(subAppId, appUser.getLinkId(), appUser.getType());
				boolean result = false;
				if (r.getCode() == 200) {
					result = true;
				}
				//判断子应用是否执行成功，未成功则手动回滚事务
				if (!result) {
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return R.fail("同步子应用失败！");
				}
			}
		}
		if (AppCategoryConstant.BUILT_IN_APP.equals(one.getCategory())) {
			if (one.getAlias().equals("twin")){
				/** 数字孪生 */
				for (AppUserEntity appUser : appUsers) {
					R<List<User>> listR = userSearchClient.listByUser(appUser.getLinkId().toString());
					User user = listR.getData().get(0);
					Long domainId = uinoUtil.addUserDefault(user.getAccount(), user.getName());
					if (domainId == 0){
						return R.fail("同步子应用失败！");
					}
					appUser.setSubUser(domainId);
				}
				app_userService.saveOrUpdateBatch(appUsers);
			}
		}
		return R.status(true);
	}

	/**
	 * 成员删除
	 */
	@PostMapping("/delete")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "成员删除", notes = "传入app_info")
	@Transactional
	public R<AppInfoEntity> delete(@ApiParam(value = "应用编号") @RequestParam String subAppId,
								   @ApiParam(value = "关联类型，1用户，2部门") @RequestParam Integer linkType,
								   @ApiParam(value = "关联id集合") @RequestParam String linkIds) {
		List<AppUserEntity> list = app_userService.list(Wrappers.<AppUserEntity>query().lambda().eq(AppUserEntity::getAppId, subAppId).eq(AppUserEntity::getLinkType, linkType).in(AppUserEntity::getLinkId, Func.toLongList(linkIds)));
		boolean remove = app_userService.remove(Wrappers.<AppUserEntity>update().lambda().eq(AppUserEntity::getAppId, subAppId).eq(AppUserEntity::getLinkType, linkType).in(AppUserEntity::getLinkId, Func.toLongList(linkIds)));
		final AppInfoEntity one = app_infoService.getOne(Wrappers.<AppInfoEntity>query().lambda().eq(AppInfoEntity::getSubAppId, subAppId));

		//同步到子应用中
		if (AppCategoryConstant.SELF_BUILT_APP.equals(one.getCategory())) {
			final R r = subAppClient.deleteUser(linkIds, linkType, subAppId);
			boolean result = false;
			if (r.getCode() == 200) {
				result = true;
			}
			//判断子应用是否执行成功，未成功则手动回滚事务
			if (!result) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return R.fail("同步子应用失败！");
			}
		} else if (AppCategoryConstant.BUILT_IN_APP.equals(one.getCategory())) {
			if (one.getAlias().equals("twin")){
				/** 数字孪生 */
				for (AppUserEntity appUser : list) {
					boolean result = uinoUtil.removeUserDefault(appUser.getSubUser());
				}
			}
		}
		if (AppCategoryConstant.IOT_APP.equals(one.getCategory())) {
			final R r = iotAppClient.deleteUser(linkIds, linkType, subAppId);
			boolean result = false;
			if (r.getCode() == 200) {
				result = true;
			}
			//判断子应用是否执行成功，未成功则手动回滚事务
			if (!result) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return R.fail("同步子应用失败！");
			}
		}
		return R.status(true);
	}

	/**
	 * 设置/取消管理员
	 */
	@PostMapping("/manager")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "设置/取消管理员", notes = "传入app_info")
	@Transactional
	public R<AppInfoEntity> manager( @RequestBody Map<String, Object> map) {
		String subAppId = (String) map.get("subAppId");
		Long linkId = Long.valueOf((String) map.get("linkId"));
		Integer isManager = (Integer) map.get("type");
		AppUserEntity one = app_userService.getOne(Wrappers.<AppUserEntity>query().lambda().eq(AppUserEntity::getAppId, subAppId).eq(AppUserEntity::getLinkType, 1).eq(AppUserEntity::getLinkId, linkId));
		if (one == null) {
			return R.fail("设置失败");
		}
		one.setType(isManager);
		app_userService.updateById(one);
		final AppInfoEntity appInfoEntity = app_infoService.getOne(Wrappers.<AppInfoEntity>query().lambda().eq(AppInfoEntity::getSubAppId, subAppId));
		//同步到子应用中
		if (AppCategoryConstant.SELF_BUILT_APP.equals(appInfoEntity.getCategory())) {
			final R r = subAppClient.setAppManager(subAppId, linkId, isManager);
			boolean result = false;
			if (r.getCode() == 200) {
				result = true;
			}
			//判断子应用是否执行成功，未成功则手动回滚事务
			if (!result) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return R.fail("同步子应用失败！");
			}
		}
		//同步到物联网子应用中
		if (AppCategoryConstant.IOT_APP.equals(appInfoEntity.getCategory())) {
			final R r = iotAppClient.setAppManager(subAppId, linkId, isManager);
			boolean result = false;
			if (r.getCode() == 200) {
				result = true;
			}
			//判断子应用是否执行成功，未成功则手动回滚事务
			if (!result) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return R.fail("同步子应用失败！");
			}
		}
		return R.status(true);
	}

	/**
	 * 可加入当前应用人员
	 */
	@GetMapping("/userListNotInApp")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "可加入当前应用人员", notes = "传入app_info")
	public R<List> userListNotInApp(@ApiParam(value = "subAppId,应用编号") @RequestParam String subAppId) {
		List<AppUserVO> appUserVOs = app_userService.list(subAppId, 1);
		List<Long> userIds = appUserVOs.stream().map(AppUserEntity::getLinkId).collect(Collectors.toList());
		R<List<User>> listR = userSearchClient.listAll();
		List<User> data = listR.getData();
		List<User> list = new ArrayList<>();
		if (data != null && data.size() > 0) {
			//过滤掉已经加入应用的用户，以及角色是超管的用户
			Long adminRoleId = 1123598816738675201L;
			list = data.stream().filter(user -> !userIds.contains(user.getId()) && !Func.toLongList(user.getRoleId()).contains(adminRoleId)).collect(Collectors.toList());
		}
		List<AppUserVO> result = new ArrayList<>();
		list.forEach(user -> {
			AppUserVO appUserVO = new AppUserVO();
			appUserVO.setLinkId(user.getId());
			appUserVO.setLinkName(user.getName());
			appUserVO.setLinkType(1);
			appUserVO.setType(ShySystemConstant.SHY_APP_USER);
			result.add(appUserVO);
		});
		return R.data(result);
	}

	/**
	 * 可加入当前应用部门
	 */
	@GetMapping("/deptListNotInApp")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "可加入当前应用部门", notes = "传入app_info")
	public R<List<Dept>> deptListNotInApp(@ApiParam(value = "subAppId,应用编号") @RequestParam String subAppId) {
		//查询当前应用所有部门
		List<AppUserVO> appDeptVOs = app_userService.list(subAppId, 2);
		List<Long> deptIds = appDeptVOs.stream().map(AppUserEntity::getLinkId).collect(Collectors.toList());
		R<List<Dept>> deptList = sysClient.getDeptList();
		List<Dept> data = deptList.getData();
		List<Dept> list = new ArrayList<>();
		if (data != null && data.size() > 0) {
			list = data.stream().filter(dept -> !deptIds.contains(dept.getId())).collect(Collectors.toList());
		}
		return R.data(list);
	}

}
